"""
读取接口实现模块
================

该模块整合各功能模块，实现完整的read函数功能。
"""

from typing import Any, Dict, List, Union, Optional
from .param_parser import ParamParser
from .address_resolver import AddressResolver
from .config_manager import ConfigManager
from .data_validator import DataValidator
from .callback_manager import CallbackManager
from .typedef import FullReadType, AddressType, DataType, ReadOption, PreReaderType, PostReaderType
from ..core.communication_interface import CommunicationInterface


class ReadInterfaceWrapper:
    """读取接口实现类"""

    @staticmethod
    def read(comm: CommunicationInterface,
             address: FullReadType,
             *args: Any,
             timeout: Optional[float] = None,
             data_type: Optional[DataType] = None,
             sync: Optional[bool] = None,
             confirm: Optional[bool] = None,
             retry: Optional[int] = None,
             raise_on_error: Optional[bool] = None,
             quality_check: Optional[bool] = None,
             preprocessors: Optional[List[PreReaderType]] = None,
             postprocessors: Optional[List[PostReaderType]] = None,
             batch_size: Optional[int] = None,
             transaction: Optional[bool] = None,
             **kwargs: Any) -> Union[
                 Any,                     # single read result
                 List[Any],               # batch read results as list
                 Dict[Any, Any],          # batch read results as dict
                 Dict[str, Any]           # config read results
             ]:
        """
        实现读取接口

        Args:
            comm: 通信接口实例
            address: 读取地址
            *args: 位置参数
            timeout: 超时时间
            data_type: 数据类型
            sync: 是否同步执行
            confirm: 是否需要确认
            retry: 重试次数
            raise_on_error: 错误时是否抛出异常
            quality_check: 是否进行质量检查
            preprocessors: 预处理器列表
            postprocessors: 后处理器列表
            batch_size: 批量大小
            transaction: 是否使用事务
            **kwargs: 关键字参数

        Returns:
            读取结果
        """
        # 1. 解析参数
        parsed_params = ParamParser.parse_read_address(address)

        # 解析位置参数和关键字参数
        pos_config = ParamParser.parse_positional_args(*args)
        kw_config = ParamParser.parse_keyword_args(**kwargs)
        merged_config = ParamParser.merge_configs(pos_config, kw_config)

        # 2. 解析地址
        address_type = parsed_params.get('address_type', 'single')
        address_info = ReadInterfaceWrapper._resolve_address(address_type, parsed_params)

        # 将解析出的数据类型、选项和长度信息合并到address_info中
        if 'data_types' in parsed_params and parsed_params['data_types']:
            address_info['data_types'] = parsed_params['data_types']
        if 'options' in parsed_params and parsed_params['options']:
            address_info['options'] = parsed_params['options']
        if 'lengths' in parsed_params and parsed_params['lengths']:
            address_info['lengths'] = parsed_params['lengths']

        # 3. 处理配置
        config = ConfigManager.create_default_config()
        config = ReadInterfaceWrapper._update_config(config, merged_config)

        # 4. 验证数据
        validation_result = DataValidator.validate_read_all(address_info, config)
        if not validation_result.get('valid', True):
            error_msg = validation_result.get('error', 'Data validation failed')
            raise ValueError(error_msg)

        # 5. 执行读取前回调
        # self.callback_manager.notify_read_start(address_info, config)

        # 6. 执行读取
        read_results = ReadInterfaceWrapper._execute_read(comm, address_type, address_info, config)

        # 7. 处理结果

        # 8. 返回结果
        return read_results

    @staticmethod
    def _resolve_address(address_type: str, parsed_params: Dict[str, Any]) -> Dict[str, Any]:
        """
        根据地址类型解析地址信息

        Args:
            address_type: 地址类型 ('single', 'batch', 'config')
            parsed_params: 解析后的参数

        Returns:
            地址信息字典
        """
        if address_type == 'single':
            return AddressResolver.resolve_read_address(parsed_params.get('addresses')[0])
        elif address_type == 'batch':
            return AddressResolver.resolve_read_address(parsed_params.get('addresses'))
        elif address_type == 'config':
            return AddressResolver.resolve_read_address(parsed_params.get('addresses'))
        else:
            return AddressResolver.resolve_read_address(parsed_params.get('addresses')[0])

    @staticmethod
    def _update_config(config: Dict[str, Any], merged_config: Dict[str, Any]) -> Dict[str, Any]:
        """
        更新配置

        Args:
            config: 配置字典
            merged_config: 合并后的配置

        Returns:
            更新后的配置字典
        """
        # 更新配置项
        config_mapping = {
            'timeout': lambda cfg, val: ConfigManager.set_timeout(cfg, val, "read"),
            'data_type': lambda cfg, val: ConfigManager.set_data_type(cfg, val, "read"),
            'sync': lambda cfg, val: ConfigManager.set_sync_mode(cfg, val, "read"),
            'retry': lambda cfg, val: ConfigManager.set_retry_count(cfg, val, "read"),
            'raise_on_error': lambda cfg, val: ConfigManager.set_error_handling(cfg, val, "read"),
            'quality_check': lambda cfg, val: ConfigManager.set_quality_check(cfg, val, "read"),
            'prereaders': lambda cfg, val: ConfigManager.set_prereaders(cfg, val),
            'postreaders': lambda cfg, val: ConfigManager.set_postreaders(cfg, val),
            'preprocessors': lambda cfg, val: ConfigManager.set_preprocessors(cfg, val),
            'postprocessors': lambda cfg, val: ConfigManager.set_postprocessors(cfg, val),
            'batch_size': lambda cfg, val: ConfigManager.set_batch_size(cfg, val, "read"),
            'confirm': lambda cfg, val: ConfigManager.set_confirmation(cfg, val),
            'transaction': lambda cfg, val: ConfigManager.set_transaction(cfg, val)
        }

        for key, setter in config_mapping.items():
            if key in merged_config:
                config = setter(config, merged_config[key])

        return config

    @staticmethod
    def _execute_read(comm: CommunicationInterface,
                      address_type: str,
                      address_info: Dict[str, Any],
                      config: Dict[str, Any]) -> Dict[str, Any]:
        """
        执行读取操作

        Args:
            comm: 通信接口实例
            address_type: 地址类型
            address_info: 地址信息
            config: 配置信息

        Returns:
            读取结果字典
        """
        try:
            if address_type == 'single':
                return ReadInterfaceWrapper._execute_single_read(comm, address_info, config)
            elif address_type == 'batch':
                return ReadInterfaceWrapper._execute_batch_read(comm, address_info, config)
            elif address_type == 'config':
                return ReadInterfaceWrapper._execute_config_read(comm, address_info, config)
            else:
                # 默认单个读取
                return ReadInterfaceWrapper._execute_single_read(comm, address_info, config)
        except Exception as e:
            raise ValueError(f"执行读取操作时出错: {str(e)}")

    @staticmethod
    def _execute_single_read(comm: CommunicationInterface,
                           address_info: Dict[str, Any],
                           config: Dict[str, Any]) -> Dict[str, Any]:
        """
        执行单个读取操作

        Args:
            comm: 通信接口实例
            address_info: 地址信息
            config: 配置信息

        Returns:
            读取结果字典
        """
        addr = address_info.get('addresses')[0]
        data_type = None

        if address_info.get('data_types'):
            data_type = address_info.get('data_types')[0]
        elif config.get('data_type'):
            data_type = config.get('data_type')

        # 构造参数
        read_kwargs = {}
        if config.get('timeout') is not None:
            read_kwargs['timeout'] = config.get('timeout')
        if data_type is not None:
            read_kwargs['data_type'] = data_type
        if config.get('sync') is not None:
            read_kwargs['sync'] = config.get('sync')

        read_result = comm.read_register(addr, **read_kwargs)
        return {addr: read_result}

    @staticmethod
    def _execute_batch_read(comm: CommunicationInterface,
                          address_info: Dict[str, Any],
                          config: Dict[str, Any]) -> Dict[str, Any]:
        """
        执行批量读取操作

        Args:
            comm: 通信接口实例
            address_info: 地址信息
            config: 配置信息

        Returns:
            读取结果字典
        """
        addresses = address_info.get('addresses', [])
        data_types = address_info.get('data_types', [])

        # 构造参数
        read_kwargs = {}
        if config.get('timeout') is not None:
            read_kwargs['timeout'] = config.get('timeout')
        if config.get('data_type') is not None:
            read_kwargs['data_type'] = config.get('data_type')
        if config.get('sync') is not None:
            read_kwargs['sync'] = config.get('sync')

        read_results = {}
        for i, addr in enumerate(addresses):
            # 获取对应的数据类型
            current_kwargs = read_kwargs.copy()
            if i < len(data_types):
                current_kwargs['data_type'] = data_types[i]
            elif config.get('data_type'):
                current_kwargs['data_type'] = config.get('data_type')
            else:
                current_kwargs.pop('data_type', None)  # 移除data_type参数

            read_results[addr] = comm.read_register(addr, **current_kwargs)

        return read_results

    @staticmethod
    def _execute_config_read(comm: CommunicationInterface,
                           address_info: Dict[str, Any],
                           config: Dict[str, Any]) -> Dict[str, Any]:
        """
        执行配置读取操作

        Args:
            comm: 通信接口实例
            address_info: 地址信息
            config: 配置信息

        Returns:
            读取结果字典
        """
        addresses = address_info.get('addresses', [])

        # 构造参数
        read_kwargs = {}
        if config.get('timeout') is not None:
            read_kwargs['timeout'] = config.get('timeout')
        if config.get('data_type') is not None:
            read_kwargs['data_type'] = config.get('data_type')
        if config.get('sync') is not None:
            read_kwargs['sync'] = config.get('sync')

        read_results = {}
        for addr in addresses:
            read_results[addr] = comm.read_register(addr, **read_kwargs)

        return read_results